package main

import (
	"bytes"
	"crypto/md5"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"strconv"
	"time"
)

var (
	AppId     = "xxxxxxxxx"                               //ID
	AppSecret = "xxxxxxxxx"                               //密钥
	URL       = "https://iot-app-prod.fengdada.cn/mk/api" //API地址
	PrinterId = "xxxxxxxxx"                               //打印机编号
)

type WaybillPrinterData struct {
	ReceiveManAddress     string `json:"receiveManAddress"`
	OrderId               string `json:"orderId"`
	NeedFetch             string `json:"needFetch"`
	PackageWeight         string `json:"packageWeight"`
	CompanyName           string `json:"companyName"`
	SendProvince          string `json:"sendProvince"`
	ErrorCode             string `json:"errorCode"`
	ReceiverProvince      string `json:"receiverProvince"`
	ReceiverCity          string `json:"receiverCity"`
	SenderMan             string `json:"senderMan"`
	SenderArea            string `json:"senderArea"`
	ReceiveMan            string `json:"receiveMan"`
	PostStationId         string `json:"postStationId"`
	ItemName              string `json:"itemName"`
	SpecialType           string `json:"specialType"`
	SenderPostcode        string `json:"senderPostcode"`
	PayMethod             string `json:"payMethod"`
	Id                    string `json:"id"`
	LogisticCode          string `json:"logisticCode"`
	MachineCode           string `json:"machineCode"`
	ErrorDesc             string `json:"errorDesc"`
	BalanceStatus         string `json:"balanceStatus"`
	SpecialMoney          string `json:"specialMoney"`
	ExpressType           string `json:"expressType"`
	SendCounty            string `json:"sendCounty"`
	Weight                string `json:"weight"`
	ReceiverPostcode      string `json:"receiverPostcode"`
	Version               string `json:"version"`
	SenderCity            string `json:"senderCity"`
	ReceiveProvince       string `json:"receiveProvince"`
	PrintResult           string `json:"printResult"`
	SendMan               string `json:"sendMan"`
	CompanyId             string `json:"companyId"`
	ExpressCost           string `json:"expressCost"`
	ReceiverManPhone      string `json:"receiverManPhone"`
	MainId                string `json:"mainId"`
	SenderManPhone        string `json:"senderManPhone"`
	Remark1               string `json:"remark1"`
	Remark3               string `json:"remark3"`
	ReceiveCounty         string `json:"receiveCounty"`
	Remark2               string `json:"remark2"`
	LastUpdateTime        string `json:"lastUpdateTime"`
	SendCity              string `json:"sendCity"`
	PkgCode               string `json:"pkgCode"`
	ReceiverMan           string `json:"receiverMan"`
	ErrorInfo             string `json:"errorInfo"`
	Remark                string `json:"remark"`
	SendManPhone          string `json:"sendManPhone"`
	BatchId               string `json:"batchId"`
	PickBy                string `json:"pickBy"`
	Result                string `json:"result"`
	MailNo                string `json:"mailNo"`
	ShippingStatus        string `json:"shippingStatus"`
	SerialVersionUID      string `json:"serialVersionUID"`
	RichItemInformation   string `json:"richItemInformation"`
	ReceiveManPhone       string `json:"receiveManPhone"`
	Udf7                  string `json:"udf7"`
	BillProvideSiteCode   string `json:"billProvideSiteCode"`
	LogisticsProviderCode string `json:"logisticsProviderCode"`
	Ddf8                  string `json:"udf8"`
	PrintCount            string `json:"printCount"`
	SenderManAddress      string `json:"senderManAddress"`
	CustId                string `json:"custId"`
	ItemWeight            string `json:"itemWeight"`
	ReceiverManAddress    string `json:"receiverManAddress"`
	IsReprint             string `json:"isReprint"`
	OrderSource           string `json:"orderSource"`
	BestSmart             string `json:"BestSmart"`
	Udf5                  string `json:"udf5"`
	Udf6                  string `json:"udf6"`
	SenderProvince        string `json:"senderProvince"`
	ReceiverArea          string `json:"receiverArea"`
	Udf3                  string `json:"udf3"`
	Udf4                  string `json:"udf4"`
	Udf1                  string `json:"udf1"`
	UserId                string `json:"userId"`
	Udf2                  string `json:"udf2"`
	PostStationName       string `json:"postStationName"`
	ItemCount             string `json:"itemCount"`
	LogisticProviderID    string `json:"logisticProviderID"`
	BillProvideSiteName   string `json:"billProvideSiteName"`
	CreateTime            string `json:"createTime"`
	ReceiveCity           string `json:"receiveCity"`
	SendManAddress        string `json:"sendManAddress"`
	PrintTime             string `json:"printTime"`
	Username              string `json:"username"`
}
type PrintData struct {
	WaybillPrinterData WaybillPrinterData `json:"waybillPrinterData"` //打印数据json字符串
	TemplateId         string             `json:"templateId"`         //打印模板id
}

//公共方法
func DoMyPost(URL string, BizData interface{}) {

	rand.Seed(time.Now().UnixNano())
	tnonce := rand.Intn(8999999999999) + 1000000000000
	nonce := strconv.Itoa(tnonce)

	p := BizData
	jsonBytes, err := json.Marshal(&p)
	if err != nil {
		fmt.Printf("序列化错误 err=%v\n", err)
	}

	bizData := string(jsonBytes)
	sign_ori := fmt.Sprintf("%s%s%s", bizData, nonce, AppSecret)

	h := md5.New()
	h.Write([]byte(sign_ori))
	md5Bytes := h.Sum(nil)
	sign := base64.StdEncoding.EncodeToString(md5Bytes)

	itime := time.Now().UnixMilli()

	requestData := map[string]string{
		"bizData":   bizData,
		"nonce":     nonce,
		"appId":     AppId,
		"timestamp": strconv.FormatInt(itime, 10),
	}
	requestBody, err := json.Marshal(requestData)
	if err != nil {
		panic(err)
	}

	req, err := http.NewRequest("POST", URL, bytes.NewReader(requestBody))
	if err != nil {
		panic(err)
	}

	req.Header.Set("Content-Type", "application/json")
	req.Header["sign"] = []string{sign}

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}

	fmt.Println("返回的数据=>", string(respBody))

}

//云打印验证码
func PrintCaptcha(PrinterId string) {
	type BizDataCaptcha struct {
		PrinterId string `json:"printerId"`
	}
	URL += "/print/captcha"
	BizData := BizDataCaptcha{PrinterId}
	DoMyPost(URL, BizData)
}

//云打印机绑定
func PrintBind(PrinterId, VerificationCode string) {
	type StructBizData struct {
		PrinterId string `json:"printerId"`
		Captcha   string `json:"captcha"`
	}
	URL += "/printer/bind"
	BizData := StructBizData{PrinterId, VerificationCode}
	DoMyPost(URL, BizData)
}

//云打印
func Print(PrinterId, ShareCode string, PrintDataList *[]PrintData) {
	type BizDataPrint struct {
		PrinterId string       `json:"printerId"`
		ShareCode string       `json:"shareCode"`
		PrintData *[]PrintData `json:"printData"`
	}
	URL += "/print"
	BizData := BizDataPrint{PrinterId, ShareCode, PrintDataList}
	DoMyPost(URL, BizData)

}

//云打印状态查询
func QueryPrintStatus(PrinterId, ShareCode string) {
	type BizDataStatus struct {
		PrinterId string `json:"printerId"`
		ShareCode string `json:"shareCode"`
	}
	URL += "/printer/status/query"
	BizData := BizDataStatus{PrinterId, ShareCode}
	DoMyPost(URL, BizData)
}

func main() {

	//1、获取验证码
	//PrintCaptcha(PrinterId)

	//2、绑定打印机
	VerificationCode := "876783"
	//PrintBind(PrinterId, VerificationCode)

	//3、云打印
	ShareCode := "611040"
	TemplateId := "206"
	//测试数据
	waybillPrinterData := WaybillPrinterData{"塘苗路18号", "10256485649", "true", "", "", "浙江省", "", "浙江省", "杭州市", "张三", "西湖区", "李四", "", "", "代收货款", "", "0", "1933", "BestSmart10256485649", "1843923524226238", "", "", " 39 元", "0", "西湖区", "", "", "1", "杭州市", "浙江省", "NONE", "张三", "", "", "18598765432", "", "15012345678", "", "", "西湖区", "", "Wed Jul 29 13:53:06 CST 2015", "测-测试单(2)(浙-2)", "杭州市", "测试测试包", "李四", "null", "【批次1/1】备注", "15012345678", "1/1", "", "SUCCESS", "12345678901234", "NOMESSAGE", "-1229572053273904313", "", "18598765432", "", "200000", "HTKY", "", "1", "教工路1号", "null", "", "塘苗路18号", "false", "BestSmart", "测试", "", "浙江省", "西湖区", "", "", "", "", "", "", "0", "HTKY", "上海分拨中心", "Wed Jul 29 13:37:40 CST 2015", "杭州市", "教工路1号", "", ""}

	printDataList := []PrintData{}
	printDataList = append(printDataList, PrintData{waybillPrinterData, TemplateId}) //如有多条，用append方法
	PData := &printDataList

	//Print(PrinterId, ShareCode, PData)

	//4、云打印机状态查询
	//QueryPrintStatus(PrinterId, ShareCode)

}
